package com.feng.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feng.constants.SystemConstants;
import com.feng.domain.ResponseResult;
import com.feng.domain.dto.AddArticleDto;
import com.feng.domain.dto.ArticleDto;
import com.feng.domain.entity.Article;
import com.feng.domain.entity.ArticleTag;
import com.feng.domain.entity.Category;
import com.feng.domain.entity.Tag;
import com.feng.domain.vo.*;
import com.feng.mapper.ArticleMapper;
import com.feng.mapper.ArticleTagMapper;
import com.feng.mapper.TagMapper;
import com.feng.service.ArticleService;
import com.feng.service.ArticleTagService;
import com.feng.service.CategoryService;
import com.feng.service.TagService;
import com.feng.util.BeanCopyUtils;
import com.feng.util.RedisCache;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ArticleTagService articleTagService;
    @Autowired
    private ArticleTagMapper articleTagMapper;
    @Autowired
    private TagMapper tagMapper;
    @Override
    public ResponseResult hotArticleList() {
        //查询热门文章，封装ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getViewCount);
        //最多只查询10条
        Page<Article> page=new Page<>(1,10);

        page(page,queryWrapper);

        List<Article> records = page.getRecords();
//        List<HotArticleVo> articleVos = new ArrayList<>();
//        //bean拷贝
//         for (Article record : records) {
//            HotArticleVo hotArticleVo=new HotArticleVo();
//            BeanUtils.copyProperties(record,hotArticleVo);
//            articleVos.add(hotArticleVo);
//        }
        List<HotArticleVo> articleVos = BeanCopyUtils.copyBeanList(records, HotArticleVo.class);



        return ResponseResult.okResult(articleVos);
    }

    @Override
    public ResponseResult articleList(Integer pageNum,Integer pageSize,Long categoryId,String inputContent) {
        //分页查询
        Page<Article> page=new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();
        //状态是正式发布的文章
        queryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_STATUS_NORMAL);
        //对isTop进行降序，置顶的文章要在最前面
        queryWrapper.orderByDesc(Article::getIsTop);
        //如果有categoryId，就要求查询时要和传入的相同
        queryWrapper.eq(Objects.nonNull(categoryId)&&categoryId>0,Article::getCategoryId,categoryId);
        //如果有标题,就要查询
        queryWrapper.like(StringUtils.hasText(inputContent),Article::getTitle,inputContent);
        page(page,queryWrapper);
        List<Article> records = page.getRecords();
        //增加了categoryname字段，用categoryid去查询进行设置
        for (Article record : records) {
            Category byId = categoryService.getById(record.getCategoryId());
            record.setCategoryName(byId.getName());

        }

        //封装查询结果
        List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(records, ArticleListVo.class);
        PageVo pageVo=new PageVo();
        long total = page.getTotal();
        pageVo.setRows(articleListVos);
        pageVo.setTotal(total);
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getArticleDetail(Long id) {
        //根据id查询文章
        Article article = this.getById(id);
        //从redis中获取viewCount
        Integer cacheMapValue = redisCache.getCacheMapValue("article:viewCount", id.toString());
        article.setViewCount(cacheMapValue.longValue());
        //根据分类id查询相应的分类名称
        Long categoryId = article.getCategoryId();
        Category category = categoryService.getById(categoryId);
        if(category!=null){
            article.setCategoryName(category.getName());
        }


        //转化成Vo
        ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);
        //分装相应返回
        return ResponseResult.okResult(articleDetailVo);
    }

    @Override
    public ResponseResult updateViewCount(Long id) {
     //更新redis中对应id的浏览量
     redisCache.incrementCacheMapValue("article:viewCount",id.toString(),1);
     return ResponseResult.okResult();
    }

    @Override
    @Transactional
    public ResponseResult add(AddArticleDto article) {
        //对象转化
        Article article1 = BeanCopyUtils.copyBean(article, Article.class);
        save(article1);
        List<Long> tags = article.getTags();
        Long id = article1.getId();


        for (Long tag : tags) {
            ArticleTag articleTag=new ArticleTag();
            articleTag.setTagId(tag);
            articleTag.setArticleId(id);
            articleTagService.save(articleTag);
        }

        return ResponseResult.okResult();

    }

    @Override
    public ResponseResult pageListArticle(ArticleDto articleDto) {
        //当前页码
        Integer pageNum = articleDto.getPageNum();
        //当前展示的最大页数
        Integer pageSize = articleDto.getPageSize();
        //分页查询
        Page<Article> page=new Page<>(pageNum,pageSize);

        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();
        //如果有传title,按文章标题模糊查询
        queryWrapper.like(StringUtils.hasText(articleDto.getTitle()),Article::getTitle,articleDto.getTitle());
        //如果有传summary,按文章摘要模糊查询
        queryWrapper.like(StringUtils.hasText(articleDto.getSummary()),Article::getSummary,articleDto.getSummary());
        //查询的是状态已发布的文章
        queryWrapper.eq(Article::getStatus,SystemConstants.ARTICLE_COMMENT);

        this.page(page,queryWrapper);
        List<Article> records = page.getRecords();
        //对象的拷贝
        List<ArticlePageVo> articlePageVos = BeanCopyUtils.copyBeanList(records, ArticlePageVo.class);

        PageVo pageVo=new PageVo(articlePageVos,page.getTotal());

        return ResponseResult.okResult(pageVo);



    }

    @Override
    public ResponseResult findArticleById(Long id) {
        //根据id查文章信息
        Article article = articleMapper.selectById(id);
        //拷贝对应的vo对象
        ArticleUpdateVo articleUpdateVo = BeanCopyUtils.copyBean(article, ArticleUpdateVo.class);

        //根据articleid查询该文章下对应的tag
        LambdaQueryWrapper<ArticleTag> queryWrapper=new LambdaQueryWrapper<>();
         queryWrapper.eq(ArticleTag::getArticleId, id);
         //根据文章筛选文章对应的标签
        List<ArticleTag> articleTags = articleTagMapper.selectList(queryWrapper);
        //stream流将tagId转化为list集合
        List<Long> collect = articleTags.stream().map(e -> e.getTagId()).collect(Collectors.toList());

        articleUpdateVo.setTags(collect);
        return ResponseResult.okResult(articleUpdateVo);
    }


    @Override
    public ResponseResult updateArticleById(ArticleUpdateVo articleUpdateVo) {
        //先保存文章信息表
        Article article = BeanCopyUtils.copyBean(articleUpdateVo, Article.class);
        this.updateById(article);
        //先将ArticleTag表所关联的标签进行删除
        articleTagMapper.deleArticleById(articleUpdateVo.getId());
        //删除后重新进行保存
        List<Long> tags = articleUpdateVo.getTags();

        Long id = article.getId();

        for (Long tag : tags) {
            ArticleTag articleTag=new ArticleTag();
            articleTag.setTagId(tag);
            articleTag.setArticleId(id);
            articleTagService.save(articleTag);
        }
        return ResponseResult.okResult();

    }

    @Override
    public ResponseResult deleArticleById(List<Long> id) {
        //根据id删除文章信息
        for (Long aLong : id) {
            articleMapper.deleteById(aLong);
            articleTagMapper.deleArticleById(aLong);
        }

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getAllArticleTitle() {
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getViewCount);
        List<Article> list = this.list(queryWrapper);
        List<String> collect = list.stream().map((e) -> {
            return e.getTitle();
        }).collect(Collectors.toList());

        return ResponseResult.okResult(collect);
    }

    @Override
    public ResponseResult updateArticleList() {
        //查询热门文章，封装ResponseResult返回
        LambdaQueryWrapper<Article> queryWrapper=new LambdaQueryWrapper<>();
        //必须是正式文章
        queryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
        //按照浏览量进行排序
        queryWrapper.orderByDesc(Article::getCreateTime);
        //最多只查询10条
        Page<Article> page=new Page<>(1,4);

        page(page,queryWrapper);

        List<Article> records = page.getRecords();

        List<HotArticleVo> articleVos = BeanCopyUtils.copyBeanList(records, HotArticleVo.class);

        return ResponseResult.okResult(articleVos);
    }

}
